'''
Created on 01/07/2012

@author: Administrador
'''
import unittest
from main.memory import Pagination_PhysicalMemory , MMU_Pagination ,Disk ,Pagination, Frame,Disk
from main.process import PCB, Instruction, Process, ProcessStatus,IOInstruction
from main.cpu import CPU
from main.dataStructures import ProcessesQueue
from main.ioDevs import IO

class TestMemory_Pagination(unittest.TestCase):
    def setUp(self):
        self.memory = Pagination_PhysicalMemory(15,Pagination(),5)
        #
        self.instruction1 =  IOInstruction(1,'Printer')
        self.instruction2 =  Instruction(ProcessStatus().IO,2)
        self.instruction3 =  Instruction(ProcessStatus().IO,3)
        self.instruction4 =  IOInstruction(4,'Printer')
        self.instruction5 =  Instruction(ProcessStatus().IO,5)
        self.instruction6 =  Instruction(ProcessStatus().IO,6)
        self.instruction7 =  Instruction(ProcessStatus().IO,7)
        self.instruction8 =  Instruction(ProcessStatus().IO,8)
        #
        self.frame0 = Frame(5)
        self.frame1 = Frame(5)
        self.frame2 = Frame(5)
        self.frame3 = Frame(5)
        self.frame4 = Frame(5)
        #
        self.process1 = Process(PCB(7))
        self.process2 = Process(PCB(7))
        self.process3 = Process(PCB(7))
        self.process4 = Process(PCB(7))
        #
        self.cpu = CPU(ProcessesQueue(),IO(),self.memory,Disk())
        
  
    def test_HasSpace(self):
        self.assertTrue(self.memory.hasSpace(0))
   
    def test_HasNotSpace(self): #Celdas con contenido diferente de none
        self.memory.cells[0] = self.frame0
        self.memory.cells[5] = self.frame1
        self.memory.cells[10]= self.frame2
        self.assertFalse(self.memory.hasSpace(0))
        
    def test_indexWithSpaces(self):
        self.memory.cells[0] = self.frame0
        self.assertTrue(self.memory.indexWithSpaces() == 5)
    
        
    
    def test_AsignationWithPagination(self):
        self.process1.addInstruction(self.instruction1)
        self.process1.addInstruction(self.instruction2)
        self.process1.addInstruction(self.instruction3)
        self.process1.addInstruction(self.instruction4)
        self.process1.addInstruction(self.instruction5)
        #
        self.frame0.addInstruction(0, self.instruction1)
        self.frame0.addInstruction(1, self.instruction2)
        self.frame0.addInstruction(2, self.instruction3)
        self.frame0.addInstruction(3, self.instruction4)
        self.frame0.addInstruction(4, self.instruction5)
        #
        self.process1.pcb.processFrames.append(self.frame0)
        #
        self.memory.addingPolicy.saveProcessInMemory(self.process1,self.memory)
        self.assertTrue(self.memory.cells[0] == self.frame0)
        
    def test_MMUwhenItHasToSearchForAPage(self):
        self.process1.addInstruction(self.instruction1)
        self.process1.addInstruction(self.instruction2)
        self.process1.addInstruction(self.instruction3)
        self.process1.addInstruction(self.instruction4)
        self.process1.addInstruction(self.instruction5)
        #
        self.frame0.addInstruction(0, self.instruction1)
        self.frame0.addInstruction(1, self.instruction2)
        self.frame0.addInstruction(2, self.instruction3)
        self.frame0.addInstruction(3, self.instruction4)
        self.frame0.addInstruction(4, self.instruction5)
        #
        self.process1.pcb.processFrames.append(self.frame0)
        #
        self.memory.cells[0] = self.frame1
        self.memory.cells[5] = self.frame0
        self.memory.cells[10] = self.frame2
        self.memory.mmu.pagesAndFrames[self.frame0] = 5
        self.memory.mmu.pagesAndFrames[self.frame1] = 0
        self.memory.mmu.pagesAndFrames[self.frame2] = 10
        #
        inst = self.memory.mmu.searchProgram(self.process1,self.memory)
        self.assertTrue(inst == self.instruction1)
        
    def test_quitProcessOfMemory(self):
        self.process1.addInstruction(self.instruction1)
        self.process1.addInstruction(self.instruction2)
        self.process1.addInstruction(self.instruction3)
        self.process1.addInstruction(self.instruction4)
        self.process1.addInstruction(self.instruction5)
        #
        self.frame0.addInstruction(0, self.instruction1)
        self.frame0.addInstruction(1, self.instruction2)
        self.frame0.addInstruction(2, self.instruction3)
        self.frame0.addInstruction(3, self.instruction4)
        self.frame0.addInstruction(4, self.instruction5)
        #
        self.process1.pcb.processFrames.append(self.frame0)
        #
        self.memory.cells[0] = self.frame1
        self.memory.cells[5] = self.frame0
        self.memory.cells[10] = self.frame2
        self.memory.mmu.pagesAndFrames[self.frame0] = 5
        self.memory.mmu.pagesAndFrames[self.frame1] = 0
        self.memory.mmu.pagesAndFrames[self.frame2] = 10
        #
        self.memory.processesTable.append(self.process1)
        #
        self.memory.quitProcessOfMemory(self.process1)
        self.assertTrue(self.memory.cells[5] == None)
        
        
    
    def test_swap(self):
        self.process1.addInstruction(self.instruction1)
        self.process1.addInstruction(self.instruction2)
        self.process1.addInstruction(self.instruction3)
        self.process1.addInstruction(self.instruction4)
        self.process1.addInstruction(self.instruction5)
        #
        self.frame0.addInstruction(0, self.instruction1)
        self.frame0.addInstruction(1, self.instruction2)
        self.frame0.addInstruction(2, self.instruction3)
        self.frame0.addInstruction(3, self.instruction4)
        self.frame0.addInstruction(4, self.instruction5)
        #
        self.process1.pcb.processFrames.append(self.frame0)
        #
        self.memory.cells[0] = self.frame0
        self.memory.cells[5] = self.frame1
        self.memory.cells[10] = self.frame3
        self.memory.mmu.pagesAndFrames[self.frame0] = 0
        self.memory.mmu.pagesAndFrames[self.frame1] = 5
        self.memory.mmu.pagesAndFrames[self.frame3] = 10
        #
        self.memory.processesTable.append(self.process1)
        #
        self.process2.addInstruction(self.instruction6)
        self.process2.addInstruction(self.instruction7)
        self.frame2.addInstruction(0, self.instruction6)
        self.frame2.addInstruction(1, self.instruction7)
        self.process2.pcb.processFrames.append(self.frame2)
        #
        self.cpu.readyProcessesQueue.append(self.process1)
        self.cpu.readyProcessesQueue.append(self.process2)
        self.memory.swap(self.process2, None,self.cpu)
        #
        self.assertTrue(self.memory.cells[0] == self.frame2)
        
    #Cuando un proceso debe ejecutar instrucciones de otra de sus paginas   
    def test_searchNewPageFromMemory(self):
        self.memory.cells[0] = self.frame0
        self.memory.cells[5] = self.frame3
        self.memory.cells[10]= self.frame2
        #
        self.process1.addInstruction(self.instruction1)
        self.process1.addInstruction(self.instruction2)
        self.process1.addInstruction(self.instruction3)
        self.process1.addInstruction(self.instruction4)
        self.process1.addInstruction(self.instruction5)
        self.process1.addInstruction(self.instruction6)
        self.process1.addInstruction(self.instruction7)
        self.process1.addInstruction(self.instruction8)
        #
        self.frame0.addInstruction(0, self.instruction1)
        self.frame0.addInstruction(1, self.instruction2)
        self.frame0.addInstruction(2, self.instruction3)
        self.frame0.addInstruction(3, self.instruction4)
        self.frame0.addInstruction(4, self.instruction5)
        #
        self.frame1.addInstruction(0, self.instruction6)
        self.frame1.addInstruction(1, self.instruction7)
        self.frame1.addInstruction(2, self.instruction8)
        #
        self.process1.pcb.processFrames.append(self.frame0) 
        self.process1.pcb.processFrames.append(self.frame1)
        #
        self.process1.pcb.currentInstruction =  self.instruction6
        #
        self.memory.mmu.pagesAndFrames[self.frame0] = 0
        self.memory.mmu.pagesAndFrames[self.frame3] = 5
        self.memory.mmu.pagesAndFrames[self.frame2] = 10
        #
        self.cpu.readyProcessesQueue.append(self.process1)
        self.memory.processesTable.append(self.process1)
        self.memory.processesTable.append(self.process2)
        self.memory.processesTable.append(self.process3)
        self.memory.processesTable.append(self.process4)
        self.process2.pcb.processFrames.append(self.frame2)
        self.process3.pcb.processFrames.append(self.frame3)
        #
        self.cpu.currentProcess = self.process1
        self.cpu.disk.addProcessToDisk(self.process1)
        #
        self.cpu.executeProcess()
        self.assertTrue(self.memory.cells[10] == self.frame1)
        
    
    
    
suite = unittest.TestLoader().loadTestsFromTestCase(TestMemory_Pagination)
unittest.TextTestRunner(verbosity=2).run(suite)